[XFRM]: skb_cow_data() does not set proper owner for new skbs.
[linux-2.6/verdex.git] / drivers / net / sk98lin / ski2c.c
blob075a0464e56b5dbf6b331a96bb45985820285d3a
1 /******************************************************************************
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
9 ******************************************************************************/
11 /******************************************************************************
13 * (C)Copyright 1998-2002 SysKonnect.
14 * (C)Copyright 2002-2003 Marvell.
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.
21 * The information in this file is provided "AS IS" without warranty.
23 ******************************************************************************/
26 * I2C Protocol
28 #if (defined(DEBUG) || ((!defined(LINT)) && (!defined(SK_SLIM))))
29 static const char SysKonnectFileId[] =
30 "@(#) $Id: ski2c.c,v 1.59 2003/10/20 09:07:25 rschmidt Exp $ (C) Marvell. ";
31 #endif
33 #include "h/skdrv1st.h" /* Driver Specific Definitions */
34 #include "h/lm80.h"
35 #include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */
37 #ifdef __C2MAN__
39 I2C protocol implementation.
41 General Description:
43 The I2C protocol is used for the temperature sensors and for
44 the serial EEPROM which hold the configuration.
46 This file covers functions that allow to read write and do
47 some bulk requests a specified I2C address.
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.
54 Note: The VPD functions are in skvpd.c
56 . PCI Config I2C Bus for VPD Data:
58 . +------------+
59 . | VPD EEPROM |
60 . +------------+
61 . |
62 . | <-- I2C
63 . |
64 . +-----------+-----------+
65 . | |
66 . +-----------------+ +-----------------+
67 . | PCI_VPD_ADR_REG | | PCI_VPD_DAT_REG |
68 . +-----------------+ +-----------------+
71 . I2C Bus for LM80 sensor:
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 . +--------+ +--------+ +----------+
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.
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
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.
107 intro()
109 #endif
111 #ifdef SK_DIAG
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.
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 */
136 #define NS2BCLK(x) (((x)*125)/10000)
139 * I2C Wire Operations
141 * About I2C_CLK_LOW():
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.
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)
156 #define NS2CLKT(x) ((x*125L)/10000)
158 /*--------------- I2C Interface Register Functions --------------- */
161 * sending one bit
163 void SkI2cSndBit(
164 SK_IOC IoC, /* I/O Context */
165 SK_U8 Bit) /* Bit to send */
167 I2C_DATA_OUT(IoC);
168 if (Bit) {
169 I2C_DATA_HIGH(IoC);
171 else {
172 I2C_DATA_LOW(IoC);
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*/
182 * Signal a start to the I2C Bus.
184 * A start is signaled when data goes to low in a high clock cycle.
186 * Ends with Clock Low.
188 * Status: not tested
190 void SkI2cStart(
191 SK_IOC IoC) /* I/O Context */
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);
200 SkDgWaitTime(IoC, NS2BCLK(T_START_SETUP));
202 /* Set Data Low */
203 I2C_DATA_LOW(IoC);
205 SkDgWaitTime(IoC, NS2BCLK(T_START_HOLD));
207 /* Clock low without Data to Input */
208 I2C_START_COND(IoC);
210 SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW));
211 } /* SkI2cStart */
214 void SkI2cStop(
215 SK_IOC IoC) /* I/O Context */
217 /* Init data and Clock to output lines */
218 /* Set Data low */
219 I2C_DATA_OUT(IoC);
220 I2C_DATA_LOW(IoC);
222 SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
224 /* Set Clock high */
225 I2C_CLK_HIGH(IoC);
227 SkDgWaitTime(IoC, NS2BCLK(T_STOP_SETUP));
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.
234 I2C_DATA_IN(IoC);
237 * When I2C activity is stopped
238 * o DATA should be set to input and
239 * o CLOCK should be set to high!
241 SkDgWaitTime(IoC, NS2BCLK(T_BUS_IDLE));
242 } /* SkI2cStop */
246 * Receive just one bit via the I2C bus.
248 * Note: Clock must be set to LOW before calling this function.
250 * Returns The received bit.
252 int SkI2cRcvBit(
253 SK_IOC IoC) /* I/O Context */
255 int Bit;
256 SK_U8 I2cSwCtrl;
258 /* Init data as input line */
259 I2C_DATA_IN(IoC);
261 SkDgWaitTime(IoC, NS2BCLK(T_CLK_2_DATA_OUT));
263 I2C_CLK_HIGH(IoC);
265 SkDgWaitTime(IoC, NS2BCLK(T_CLK_HIGH));
267 SK_I2C_GET_SW(IoC, &I2cSwCtrl);
269 Bit = (I2cSwCtrl & I2C_DATA) ? 1 : 0;
271 I2C_CLK_LOW(IoC);
272 SkDgWaitTime(IoC, NS2BCLK(T_CLK_LOW-T_CLK_2_DATA_OUT));
274 return(Bit);
275 } /* SkI2cRcvBit */
279 * Receive an ACK.
281 * returns 0 If acknowledged
282 * 1 in case of an error
284 int SkI2cRcvAck(
285 SK_IOC IoC) /* I/O Context */
288 * Received bit must be zero.
290 return(SkI2cRcvBit(IoC) != 0);
291 } /* SkI2cRcvAck */
295 * Send an NACK.
297 void SkI2cSndNAck(
298 SK_IOC IoC) /* I/O Context */
301 * Received bit must be zero.
303 SkI2cSndBit(IoC, 1);
304 } /* SkI2cSndNAck */
308 * Send an ACK.
310 void SkI2cSndAck(
311 SK_IOC IoC) /* I/O Context */
314 * Received bit must be zero.
316 SkI2cSndBit(IoC, 0);
317 } /* SkI2cSndAck */
321 * Send one byte to the I2C device and wait for ACK.
323 * Return acknowleged status.
325 int SkI2cSndByte(
326 SK_IOC IoC, /* I/O Context */
327 int Byte) /* byte to send */
329 int i;
331 for (i = 0; i < 8; i++) {
332 if (Byte & (1<<(7-i))) {
333 SkI2cSndBit(IoC, 1);
335 else {
336 SkI2cSndBit(IoC, 0);
340 return(SkI2cRcvAck(IoC));
341 } /* SkI2cSndByte */
345 * Receive one byte and ack it.
347 * Return byte.
349 int SkI2cRcvByte(
350 SK_IOC IoC, /* I/O Context */
351 int Last) /* Last Byte Flag */
353 int i;
354 int Byte = 0;
356 for (i = 0; i < 8; i++) {
357 Byte <<= 1;
358 Byte |= SkI2cRcvBit(IoC);
361 if (Last) {
362 SkI2cSndNAck(IoC);
364 else {
365 SkI2cSndAck(IoC);
368 return(Byte);
369 } /* SkI2cRcvByte */
373 * Start dialog and send device address
375 * Return 0 if acknowleged, 1 in case of an error
377 int SkI2cSndDev(
378 SK_IOC IoC, /* I/O Context */
379 int Addr, /* Device Address */
380 int Rw) /* Read / Write Flag */
382 SkI2cStart(IoC);
383 Rw = ~Rw;
384 Rw &= I2C_WRITE;
385 return(SkI2cSndByte(IoC, (Addr<<1) | Rw));
386 } /* SkI2cSndDev */
388 #endif /* SK_DIAG */
390 /*----------------- I2C CTRL Register Functions ----------*/
393 * waits for a completion of an I2C transfer
395 * returns 0: success, transfer completes
396 * 1: error, transfer does not complete, I2C transfer
397 * killed, wait loop terminated.
399 int SkI2cWait(
400 SK_AC *pAC, /* Adapter Context */
401 SK_IOC IoC, /* I/O Context */
402 int Event) /* complete event to wait for (I2C_READ or I2C_WRITE) */
404 SK_U64 StartTime;
405 SK_U64 CurrentTime;
406 SK_U32 I2cCtrl;
408 StartTime = SkOsGetTime(pAC);
410 do {
411 CurrentTime = SkOsGetTime(pAC);
413 if (CurrentTime - StartTime > SK_TICKS_PER_SEC / 8) {
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);
422 SK_I2C_GET_CTL(IoC, &I2cCtrl);
424 #ifdef xYUKON_DBG
425 printf("StartTime=%lu, CurrentTime=%lu\n",
426 StartTime, CurrentTime);
427 if (kbhit()) {
428 return(1);
430 #endif /* YUKON_DBG */
432 } while ((I2cCtrl & I2C_FLAG) == (SK_U32)Event << 31);
434 return(0);
435 } /* SkI2cWait */
439 * waits for a completion of an I2C transfer
441 * Returns
442 * Nothing
444 void SkI2cWaitIrq(
445 SK_AC *pAC, /* Adapter Context */
446 SK_IOC IoC) /* I/O Context */
448 SK_SENSOR *pSen;
449 SK_U64 StartTime;
450 SK_U32 IrqSrc;
452 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
454 if (pSen->SenState == SK_SEN_IDLE) {
455 return;
458 StartTime = SkOsGetTime(pAC);
460 do {
461 if (SkOsGetTime(pAC) - StartTime > SK_TICKS_PER_SEC / 8) {
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;
470 SK_IN32(IoC, B0_ISRC, &IrqSrc);
472 } while ((IrqSrc & IS_I2C_READY) == 0);
474 pSen->SenState = SK_SEN_IDLE;
475 return;
476 } /* SkI2cWaitIrq */
479 * writes a single byte or 4 bytes into the I2C device
481 * returns 0: success
482 * 1: error
484 int SkI2cWrite(
485 SK_AC *pAC, /* Adapter Context */
486 SK_IOC IoC, /* I/O Context */
487 SK_U32 I2cData, /* I2C Data to write */
488 int I2cDev, /* I2C Device Address */
489 int I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
490 int I2cReg, /* I2C Device Register Address */
491 int I2cBurst) /* I2C Burst Flag */
493 SK_OUT32(IoC, B2_I2C_DATA, I2cData);
495 SK_I2C_CTL(IoC, I2C_WRITE, I2cDev, I2cDevSize, I2cReg, I2cBurst);
497 return(SkI2cWait(pAC, IoC, I2C_WRITE));
498 } /* SkI2cWrite*/
501 #ifdef SK_DIAG
503 * reads a single byte or 4 bytes from the I2C device
505 * returns the word read
507 SK_U32 SkI2cRead(
508 SK_AC *pAC, /* Adapter Context */
509 SK_IOC IoC, /* I/O Context */
510 int I2cDev, /* I2C Device Address */
511 int I2cDevSize, /* I2C Device Size (e.g. I2C_025K_DEV or I2C_2K_DEV) */
512 int I2cReg, /* I2C Device Register Address */
513 int I2cBurst) /* I2C Burst Flag */
515 SK_U32 Data;
517 SK_OUT32(IoC, B2_I2C_DATA, 0);
518 SK_I2C_CTL(IoC, I2C_READ, I2cDev, I2cDevSize, I2cReg, I2cBurst);
520 if (SkI2cWait(pAC, IoC, I2C_READ) != 0) {
521 w_print("%s\n", SKERR_I2C_E002MSG);
524 SK_IN32(IoC, B2_I2C_DATA, &Data);
526 return(Data);
527 } /* SkI2cRead */
528 #endif /* SK_DIAG */
532 * read a sensor's value
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)
541 int SkI2cReadSensor(
542 SK_AC *pAC, /* Adapter Context */
543 SK_IOC IoC, /* I/O Context */
544 SK_SENSOR *pSen) /* Sensor to be read */
546 if (pSen->SenRead != NULL) {
547 return((*pSen->SenRead)(pAC, IoC, pSen));
549 else {
550 return(0); /* no success */
552 } /* SkI2cReadSensor */
555 * Do the Init state 0 initialization
557 static int SkI2cInit0(
558 SK_AC *pAC) /* Adapter Context */
560 int i;
562 /* Begin with first sensor */
563 pAC->I2c.CurrSens = 0;
565 /* Begin with timeout control for state machine */
566 pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
568 /* Set sensor number to zero */
569 pAC->I2c.MaxSens = 0;
571 #ifndef SK_DIAG
572 /* Initialize Number of Dummy Reads */
573 pAC->I2c.DummyReads = SK_MAX_SENSORS;
574 #endif
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;
594 /* Now we are "INIT data"ed */
595 pAC->I2c.InitLevel = SK_INIT_DATA;
596 return(0);
597 } /* SkI2cInit0*/
601 * Do the init state 1 initialization
603 * initialize the following register of the LM80:
604 * Configuration register:
605 * - START, noINT, activeLOW, noINT#Clear, noRESET, noCI, noGPO#, noINIT
607 * Interrupt Mask Register 1:
608 * - all interrupts are Disabled (0xff)
610 * Interrupt Mask Register 2:
611 * - all interrupts are Disabled (0xff) Interrupt modi doesn't matter.
613 * Fan Divisor/RST_OUT register:
614 * - Divisors set to 1 (bits 00), all others 0s.
616 * OS# Configuration/Temperature resolution Register:
617 * - all 0s
620 static int SkI2cInit1(
621 SK_AC *pAC, /* Adapter Context */
622 SK_IOC IoC) /* I/O Context */
624 int i;
625 SK_U8 I2cSwCtrl;
626 SK_GEPORT *pPrt; /* GIni Port struct pointer */
628 if (pAC->I2c.InitLevel != SK_INIT_DATA) {
629 /* ReInit not needed in I2C module */
630 return(0);
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);
638 if ((I2cSwCtrl & I2C_DATA) == 0) {
639 /* this is a 32-Bit board */
640 pAC->GIni.GIYukon32Bit = SK_TRUE;
641 return(0);
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);
649 (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_1, 0);
651 (void)SkI2cWrite(pAC, IoC, 0xffUL, LM80_ADDR, I2C_025K_DEV, LM80_IMSK_2, 0);
653 (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_FAN_CTRL, 0);
655 (void)SkI2cWrite(pAC, IoC, 0, LM80_ADDR, I2C_025K_DEV, LM80_TEMP_CTRL, 0);
657 (void)SkI2cWrite(pAC, IoC, (SK_U32)LM80_CFG_START, LM80_ADDR, I2C_025K_DEV,
658 LM80_CFG, 0);
661 * MaxSens has to be updated here, because PhyType is not
662 * set when performing Init Level 0
664 pAC->I2c.MaxSens = 5;
666 pPrt = &pAC->GIni.GP[0];
668 if (pAC->GIni.GIGenesis) {
669 if (pPrt->PhyType == SK_PHY_BCOM) {
670 if (pAC->GIni.GIMacsFound == 1) {
671 pAC->I2c.MaxSens += 1;
673 else {
674 pAC->I2c.MaxSens += 3;
678 else {
679 pAC->I2c.MaxSens += 3;
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;
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;
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;
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;
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;
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;
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";
776 else {
777 pAC->I2c.SenTable[i].SenDesc = "Voltage PHY 3V3";
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;
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;
805 break;
806 default:
807 SK_ERR_LOG(pAC, SK_ERRCL_INIT | SK_ERRCL_SW,
808 SKERR_I2C_E001, SKERR_I2C_E001MSG);
809 break;
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;
821 #ifndef SK_DIAG
822 pAC->I2c.DummyReads = pAC->I2c.MaxSens;
823 #endif /* !SK_DIAG */
825 /* Clear I2C IRQ */
826 SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
828 /* Now we are I/O initialized */
829 pAC->I2c.InitLevel = SK_INIT_IO;
830 return(0);
831 } /* SkI2cInit1 */
835 * Init level 2: Start first sensor read.
837 static int SkI2cInit2(
838 SK_AC *pAC, /* Adapter Context */
839 SK_IOC IoC) /* I/O Context */
841 int ReadComplete;
842 SK_SENSOR *pSen;
844 if (pAC->I2c.InitLevel != SK_INIT_IO) {
845 /* ReInit not needed in I2C module */
846 /* Init0 and Init2 not permitted */
847 return(0);
850 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
851 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
853 if (ReadComplete) {
854 SK_ERR_LOG(pAC, SK_ERRCL_INIT, SKERR_I2C_E008, SKERR_I2C_E008MSG);
857 /* Now we are correctly initialized */
858 pAC->I2c.InitLevel = SK_INIT_RUN;
860 return(0);
861 } /* SkI2cInit2*/
865 * Initialize I2C devices
867 * Get the first voltage value and discard it.
868 * Go into temperature read mode. A default pointer is not set.
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.
878 * return:
879 * 0 = success
880 * other = error.
882 int SkI2cInit(
883 SK_AC *pAC, /* Adapter Context */
884 SK_IOC IoC, /* I/O Context needed in levels 1 and 2 */
885 int Level) /* Init Level */
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;
899 return(0);
900 } /* SkI2cInit */
903 #ifndef SK_DIAG
906 * Interrupt service function for the I2C Interface
908 * Clears the Interrupt source
910 * Reads the register and check it for sending a trap.
912 * Starts the timer if necessary.
914 void SkI2cIsr(
915 SK_AC *pAC, /* Adapter Context */
916 SK_IOC IoC) /* I/O Context */
918 SK_EVPARA Para;
920 /* Clear I2C IRQ */
921 SK_OUT32(IoC, B2_I2C_IRQ, I2C_CLR_IRQ);
923 Para.Para64 = 0;
924 SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_IRQ, Para);
925 } /* SkI2cIsr */
929 * Check this sensors Value against the threshold and send events.
931 static void SkI2cCheckSensor(
932 SK_AC *pAC, /* Adapter Context */
933 SK_SENSOR *pSen)
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 */
943 /* Check Dummy Reads first */
944 if (pAC->I2c.DummyReads > 0) {
945 pAC->I2c.DummyReads--;
946 return;
949 /* Get the current time */
950 CurrTime = SkOsGetTime(pAC);
952 /* Set para to the most useful setting: The current sensor. */
953 ParaLocal.Para64 = (SK_U64)pAC->I2c.CurrSens;
955 /* Check the Value against the thresholds. First: Error Thresholds */
956 TooHigh = (pSen->SenValue > pSen->SenThreErrHigh);
957 TooLow = (pSen->SenValue < pSen->SenThreErrLow);
959 IsError = SK_FALSE;
960 if (TooHigh || TooLow) {
961 /* Error condition is satisfied */
962 DoTrapSend = SK_TRUE;
963 DoErrLog = SK_TRUE;
965 /* Now error condition is satisfied */
966 IsError = SK_TRUE;
968 if (pSen->SenErrFlag == SK_SEN_ERR_ERR) {
969 /* This state is the former one */
971 /* So check first whether we have to send a trap */
972 if (pSen->SenLastErrTrapTS + SK_SEN_ERR_TR_HOLD >
973 CurrTime) {
975 * Do NOT send the Trap. The hold back time
976 * has to run out first.
978 DoTrapSend = SK_FALSE;
981 /* Check now whether we have to log an Error */
982 if (pSen->SenLastErrLogTS + SK_SEN_ERR_LOG_HOLD >
983 CurrTime) {
985 * Do NOT log the error. The hold back time
986 * has to run out first.
988 DoErrLog = SK_FALSE;
991 else {
992 /* We came from a different state -> Set Begin Time Stamp */
993 pSen->SenBegErrTS = CurrTime;
994 pSen->SenErrFlag = SK_SEN_ERR_ERR;
997 if (DoTrapSend) {
998 /* Set current Time */
999 pSen->SenLastErrTrapTS = CurrTime;
1000 pSen->SenErrCts++;
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);
1009 if (DoErrLog) {
1010 /* Set current Time */
1011 pSen->SenLastErrLogTS = CurrTime;
1013 if (pSen->SenType == SK_SEN_TEMP) {
1014 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E011, SKERR_I2C_E011MSG);
1016 else if (pSen->SenType == SK_SEN_VOLT) {
1017 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E012, SKERR_I2C_E012MSG);
1019 else {
1020 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E015, SKERR_I2C_E015MSG);
1025 /* Check the Value against the thresholds */
1026 /* 2nd: Warning thresholds */
1027 TooHigh = (pSen->SenValue > pSen->SenThreWarnHigh);
1028 TooLow = (pSen->SenValue < pSen->SenThreWarnLow);
1030 if (!IsError && (TooHigh || TooLow)) {
1031 /* Error condition is satisfied */
1032 DoTrapSend = SK_TRUE;
1033 DoErrLog = SK_TRUE;
1035 if (pSen->SenErrFlag == SK_SEN_ERR_WARN) {
1036 /* This state is the former one */
1038 /* So check first whether we have to send a trap */
1039 if (pSen->SenLastWarnTrapTS + SK_SEN_WARN_TR_HOLD > CurrTime) {
1041 * Do NOT send the Trap. The hold back time
1042 * has to run out first.
1044 DoTrapSend = SK_FALSE;
1047 /* Check now whether we have to log an Error */
1048 if (pSen->SenLastWarnLogTS + SK_SEN_WARN_LOG_HOLD > CurrTime) {
1050 * Do NOT log the error. The hold back time
1051 * has to run out first.
1053 DoErrLog = SK_FALSE;
1056 else {
1057 /* We came from a different state -> Set Begin Time Stamp */
1058 pSen->SenBegWarnTS = CurrTime;
1059 pSen->SenErrFlag = SK_SEN_ERR_WARN;
1062 if (DoTrapSend) {
1063 /* Set current Time */
1064 pSen->SenLastWarnTrapTS = CurrTime;
1065 pSen->SenWarnCts++;
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);
1074 if (DoErrLog) {
1075 /* Set current Time */
1076 pSen->SenLastWarnLogTS = CurrTime;
1078 if (pSen->SenType == SK_SEN_TEMP) {
1079 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E009, SKERR_I2C_E009MSG);
1081 else if (pSen->SenType == SK_SEN_VOLT) {
1082 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E010, SKERR_I2C_E010MSG);
1084 else {
1085 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E014, SKERR_I2C_E014MSG);
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;
1096 /* End of check against the thresholds */
1098 /* Bug fix AF: 16.Aug.2001: Correct the init base
1099 * of LM80 sensor.
1101 if (pSen->SenInit == SK_SEN_DYN_INIT_PCI_IO) {
1103 pSen->SenInit = SK_SEN_DYN_INIT_NONE;
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;
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;
1117 #ifdef TEST_ONLY
1118 /* Dynamic thresholds also for VAUX of LM80 sensor */
1119 if (pSen->SenInit == SK_SEN_DYN_INIT_VAUX) {
1121 pSen->SenInit = SK_SEN_DYN_INIT_NONE;
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;
1128 /* 0V VAUX Voltage */
1129 else {
1130 pSen->SenThreWarnHigh = SK_SEN_VAUX_0V_WARN_ERR;
1131 pSen->SenThreErrHigh = SK_SEN_VAUX_0V_WARN_ERR;
1136 * Check initialization state:
1137 * The VIO Thresholds need adaption
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;
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;
1154 #endif
1156 if (pSen->SenInit != SK_SEN_DYN_INIT_NONE) {
1157 SK_ERR_LOG(pAC, SK_ERRCL_HW, SKERR_I2C_E013, SKERR_I2C_E013MSG);
1159 } /* SkI2cCheckSensor */
1163 * The only Event to be served is the timeout event
1166 int SkI2cEvent(
1167 SK_AC *pAC, /* Adapter Context */
1168 SK_IOC IoC, /* I/O Context */
1169 SK_U32 Event, /* Module specific Event */
1170 SK_EVPARA Para) /* Event specific Parameter */
1172 int ReadComplete;
1173 SK_SENSOR *pSen;
1174 SK_U32 Time;
1175 SK_EVPARA ParaLocal;
1176 int i;
1178 /* New case: no sensors */
1179 if (pAC->I2c.MaxSens == 0) {
1180 return(0);
1183 switch (Event) {
1184 case SK_I2CEV_IRQ:
1185 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1186 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1188 if (ReadComplete) {
1189 /* Check sensor against defined thresholds */
1190 SkI2cCheckSensor(pAC, pSen);
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;
1198 else {
1199 Time = SK_I2C_TIM_SHORT;
1202 /* Start Timer */
1203 ParaLocal.Para64 = (SK_U64)0;
1205 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1207 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1208 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1210 else {
1211 /* Start Timer */
1212 ParaLocal.Para64 = (SK_U64)0;
1214 pAC->I2c.TimerMode = SK_TIMER_WATCH_SM;
1216 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, SK_I2C_TIM_WATCH,
1217 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1219 break;
1220 case SK_I2CEV_TIM:
1221 if (pAC->I2c.TimerMode == SK_TIMER_NEW_GAUGING) {
1223 ParaLocal.Para64 = (SK_U64)0;
1224 SkTimerStop(pAC, IoC, &pAC->I2c.SenTimer);
1226 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1227 ReadComplete = SkI2cReadSensor(pAC, IoC, pSen);
1229 if (ReadComplete) {
1230 /* Check sensor against defined thresholds */
1231 SkI2cCheckSensor(pAC, pSen);
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;
1239 else {
1240 Time = SK_I2C_TIM_SHORT;
1243 /* Start Timer */
1244 ParaLocal.Para64 = (SK_U64)0;
1246 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1248 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1249 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
1252 else {
1253 pSen = &pAC->I2c.SenTable[pAC->I2c.CurrSens];
1254 pSen->SenErrFlag = SK_SEN_ERR_FAULTY;
1255 SK_I2C_STOP(IoC);
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;
1263 else {
1264 Time = SK_I2C_TIM_SHORT;
1267 /* Start Timer */
1268 ParaLocal.Para64 = (SK_U64)0;
1270 pAC->I2c.TimerMode = SK_TIMER_NEW_GAUGING;
1272 SkTimerStart(pAC, IoC, &pAC->I2c.SenTimer, Time,
1273 SKGE_I2C, SK_I2CEV_TIM, ParaLocal);
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;
1288 break;
1289 default:
1290 SK_ERR_LOG(pAC, SK_ERRCL_SW, SKERR_I2C_E006, SKERR_I2C_E006MSG);
1293 return(0);
1294 } /* SkI2cEvent*/
1296 #endif /* !SK_DIAG */