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