Annotation of XNU/iokit/Drivers/audio/drvPPCDACA/PPCI2CInterface.cpp, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*
                     23:  * Copyright (c) 1998 Apple Computer, Inc.  All rights reserved.
                     24:  *
                     25:  * Implementation of the interface for the keylargo I2C interface
                     26:  *
                     27:  * HISTORY
                     28:  *
                     29:  */
                     30: 
                     31: #include "PPCI2CInterface.h"
                     32: 
                     33: // Uncomment the following define if you wish ro see more logging
                     34: // on the i2c interface:
                     35: // #define DEBUGMODE 
                     36: 
                     37: // Private Methods:
                     38: // ===============
                     39: 
                     40: // FIXME: change the if 0 into if 1 in the following line for final
                     41: // builds so all the simple private functions can be inlined.
                     42: #if 1
                     43: #define INLINE inline
                     44: #else
                     45: #define INLINE
                     46: #endif
                     47: 
                     48: // --------------------------------------------------------------------------
                     49: // Method: dumpI2CRegisters
                     50: //
                     51: // Purpose:
                     52: //        Given the base of the i2c registers inits all the registers
                     53: INLINE void
                     54: PPCI2CInterface::dumpI2CRegisters()
                     55: {
                     56: #ifdef DEBUGMODE
                     57:     IOLog("mode    0x%08lx -> 0x%02x\n", (UInt32)mode,*mode);
                     58:     IOLog("control 0x%08lx -> 0x%02x\n", (UInt32)control,*control);
                     59:     IOLog("status  0x%08lx -> 0x%02x\n", (UInt32)status,*status);
                     60:     IOLog("ISR     0x%08lx -> 0x%02x\n", (UInt32)ISR,*ISR);
                     61:     IOLog("IER     0x%08lx -> 0x%02x\n", (UInt32)IER,*IER);
                     62:     IOLog("address 0x%08lx -> 0x%02x\n", (UInt32)address,*address);
                     63:     IOLog("subAddr 0x%08lx -> 0x%02x\n", (UInt32)subAddr,*subAddr);
                     64:     //IOLog("data    0x%08lx -> 0x%02x\n", (UInt32)data,*data);
                     65: #endif //DEBUGMODE
                     66: }
                     67: 
                     68: // --------------------------------------------------------------------------
                     69: // Method: SetI2CBase
                     70: //
                     71: // Purpose:
                     72: //        Given the base of the i2c registers inits all the registers
                     73: INLINE void
                     74: PPCI2CInterface::SetI2CBase(UInt8 *baseAddress, UInt8 steps)
                     75: {
                     76:     I2CRegister base = (I2CRegister)baseAddress;
                     77: 
                     78:     if (base != NULL) {
                     79:         mode = base;                                                                           // Configure the transmission mode of the i2c cell and the databit rate.
                     80:         control = mode + steps;                         // Holds the 4 bits used to start the operations on the i2c interface.
                     81:         status = control + steps;              // Status bits for the i2 cell and the i2c interface.
                     82:         ISR = status + steps;                                          // Holds the status bits for the interrupt conditions.
                     83:         IER = ISR + steps;                                               // Eneables the bits that allow the four interrupt status conditions.
                     84:         address = IER + steps;                   // Holds the 7 bits address and the R/W bit.
                     85:         subAddr = address + steps; // the 8bit subaddress..
                     86:         data = subAddr + steps;                        // from where we read and write data
                     87: 
                     88:         // Clears interrupt and status register:
                     89:         *status = 0x00;
                     90:         *ISR = 0x00;
                     91: 
                     92:         // And remembers the current mode:
                     93:         getMode();
                     94: 
                     95: #ifdef DEBUGMODE
                     96:         IOLog("PPCI2CInterface::SetI2CBase(0x%08lx,0x%02x)\n",(UInt32)baseAddress, steps);
                     97:         dumpI2CRegisters();
                     98: #endif // DEBUGMODE
                     99:     }
                    100: }
                    101: 
                    102: // --------------------------------------------------------------------------
                    103: // Method: shiftedMask
                    104: //
                    105: // Purpose:
                    106: //        Returns the mask to use with the register:
                    107: INLINE UInt8
                    108: PPCI2CInterface::shiftedMask(UInt8 mask, UInt8 shift)
                    109: {
                    110:     return (mask << shift);
                    111: }
                    112: 
                    113: // --------------------------------------------------------------------------
                    114: // Method: shiftedCompMask
                    115: //
                    116: // Purpose:
                    117: //        Returns the complement of the mask
                    118: INLINE UInt8
                    119: PPCI2CInterface::shiftedCompMask(UInt8 mask, UInt8 shift)
                    120: {
                    121:     return ~shiftedMask(mask, shift);
                    122: }
                    123: 
                    124: // --------------------------------------------------------------------------
                    125: // Method: writeRegisterField
                    126: //
                    127: // Purpose:
                    128: //        writes a field of a regiter with the given data. The arguments are
                    129: //        the register, the mask for the field, shift to get to the right bits
                    130: //        and the new data.
                    131: INLINE void
                    132: PPCI2CInterface::writeRegisterField(I2CRegister reg, UInt8 mask, UInt8 shift, UInt8 newData)
                    133: {
                    134:     UInt8 registerValue = *reg;
                    135:     UInt8 data = (newData & mask);
                    136:     UInt8 nMask = shiftedCompMask(mask, shift);
                    137: 
                    138:     *reg = (registerValue & nMask) | (data << shift);
                    139:     eieio();
                    140:  
                    141: #ifdef DEBUGMODE
                    142: /*    IOLog("PPCI2CInterface::writeRegisterField(0x%08lx, 0x%02x, 0x%02x, 0x%02x)\n",(UInt32)reg, mask, shift, newData);
                    143:     IOLog("PPCI2CInterface::writeRegisterField() registerValue=0x%02x\n", registerValue);
                    144:     IOLog("PPCI2CInterface::writeRegisterField() data=0x%02x\n", data);
                    145:     IOLog("PPCI2CInterface::writeRegisterField() nMask=0x%02x\n", nMask);
                    146:     IOLog("PPCI2CInterface::writeRegisterField() *reg=0x%02x\n", *reg);*/
                    147: #endif // DEBUGMODE
                    148: }
                    149: 
                    150: // --------------------------------------------------------------------------
                    151: // Method: readRegisterField
                    152: //
                    153: // Purpose:
                    154: //        writes a field of a regiter with the given data. The arguments are
                    155: //        the register, the mask for the field and shift to get to the right
                    156: //        bits.
                    157: INLINE UInt8
                    158: PPCI2CInterface::readRegisterField(I2CRegister reg, UInt8 mask, UInt8 shift)
                    159: {
                    160:     UInt8 registerValue = *reg;
                    161:     UInt8 returnValue = ((registerValue) >> shift) & mask;
                    162: 
                    163: #ifdef DEBUGMODE
                    164: /*    IOLog("PPCI2CInterface::readRegisterField(0x%08lx, 0x%02x, 0x%02x)\n",(UInt32)reg, mask, shift);
                    165:     IOLog("PPCI2CInterface::readRegisterField() *reg=0x%02x\n", *reg);
                    166:     IOLog("PPCI2CInterface::readRegisterField() returnValue=0x%02x\n", returnValue);*/
                    167: #endif // DEBUGMODE
                    168: 
                    169:     return returnValue;
                    170: }
                    171: 
                    172: // Intermediate methods to access to each field of all the registers:
                    173: // ------------------------------------------------------------------
                    174: 
                    175: // Mode register
                    176: INLINE void
                    177: PPCI2CInterface::setMode(I2CMode newMode)
                    178: {
                    179:     // remoeber the last mode:
                    180:     lastMode = newMode;
                    181:     writeRegisterField(mode, (UInt8)kModeMask, (UInt8)I2CModeShift, (UInt8)newMode);
                    182: }
                    183: 
                    184: INLINE PPCI2CInterface::I2CMode
                    185: PPCI2CInterface::getMode()
                    186: {
                    187:     lastMode = (I2CMode)readRegisterField(mode, (UInt8)kModeMask, (UInt8)I2CModeShift);
                    188:     return lastMode;
                    189: }
                    190: 
                    191: INLINE void
                    192: PPCI2CInterface::setSpeed(I2CSpeed newSpeed)
                    193: {
                    194:     writeRegisterField(mode, (UInt8)kSpeedMask, (UInt8)I2CSpeedShift, (UInt8)newSpeed);
                    195: }
                    196: 
                    197: INLINE PPCI2CInterface::I2CSpeed
                    198: PPCI2CInterface::getSpeed()
                    199: {
                    200:     return (I2CSpeed)readRegisterField(mode, (UInt8)kSpeedMask, (UInt8)I2CSpeedShift);
                    201: }
                    202: 
                    203: // Control register
                    204: INLINE void
                    205: PPCI2CInterface::setControl(I2CControl newControlValue)
                    206: {
                    207:     *control = (UInt8)newControlValue;
                    208:     eieio();
                    209: }
                    210: 
                    211: INLINE PPCI2CInterface::I2CControl
                    212: PPCI2CInterface::getControl()
                    213: {
                    214:     return (I2CControl)(*control);
                    215: }
                    216: 
                    217: // Status register
                    218: INLINE void
                    219: PPCI2CInterface::setStatus(I2CStatus newStatusValue)
                    220: {
                    221:     *status = (UInt8)newStatusValue;
                    222:     eieio();
                    223: }
                    224: 
                    225: INLINE PPCI2CInterface::I2CStatus
                    226: PPCI2CInterface::getStatus()
                    227: {
                    228:     return (I2CStatus)(*status);
                    229: }
                    230: 
                    231: // Interrupt status
                    232: INLINE void
                    233: PPCI2CInterface::setInterruptStatus(I2CInterruptStatus newStatusValue)
                    234: {
                    235:     *ISR = (UInt8)newStatusValue;
                    236:     eieio();
                    237: }
                    238: 
                    239: INLINE PPCI2CInterface::I2CInterruptStatus
                    240: PPCI2CInterface::getInterruptStatus()
                    241: {
                    242:     return (I2CInterruptStatus)(*ISR);
                    243: }
                    244: 
                    245: // Interrupt enable
                    246: INLINE void
                    247: PPCI2CInterface::setInterruptEnable(I2CInterruptEnable newInterruptEnable)
                    248: {
                    249:     *IER = (UInt8)newInterruptEnable;
                    250:     eieio();
                    251: }
                    252: 
                    253: INLINE PPCI2CInterface::I2CInterruptEnable
                    254: PPCI2CInterface::setInterruptEnable()
                    255: {
                    256:     return (I2CInterruptEnable)(*IER);
                    257: }
                    258: 
                    259: // Address Register:
                    260: INLINE void
                    261: PPCI2CInterface::setAddress(UInt8 newAddress)
                    262: {
                    263:     writeRegisterField(address, (UInt8)kADDRMask, (UInt8)I2CAddressShift, (UInt8)newAddress);
                    264:     eieio();
                    265: }
                    266: 
                    267: INLINE void
                    268: PPCI2CInterface::setAddressRegister(UInt8 newAddress, I2CRWMode readMode)
                    269: {
                    270:     newAddress &= kADDRMask;
                    271:     *address = (newAddress << I2CAddressShift) | readMode;
                    272:     eieio();
                    273: }
                    274: 
                    275: INLINE UInt8
                    276: PPCI2CInterface::getAddress()
                    277: {
                    278:     return readRegisterField(address, (UInt8)kADDRMask, (UInt8)I2CAddressShift);
                    279: }
                    280: 
                    281: INLINE void
                    282: PPCI2CInterface::setReadWrite(I2CRWMode readMode)
                    283: {
                    284:     writeRegisterField(address, (UInt8)kRWMask, (UInt8)I2CRWShift, (UInt8)readMode);
                    285:     eieio();
                    286: }
                    287: 
                    288: INLINE PPCI2CInterface::I2CRWMode
                    289: PPCI2CInterface::getReadWrite()
                    290: {
                    291:     return (I2CRWMode)readRegisterField(address, (UInt8)kRWMask, (UInt8)I2CRWShift);
                    292: }
                    293: 
                    294: // SubAddress register
                    295: INLINE void
                    296: PPCI2CInterface::setSubAddress(UInt8 newSubAddress)
                    297: {
                    298:     *subAddr = newSubAddress;
                    299:     eieio();
                    300: }
                    301: 
                    302: INLINE UInt8
                    303: PPCI2CInterface::getSubAddress()
                    304: {
                    305:     return (*subAddr);
                    306: }
                    307: 
                    308: // Data register
                    309: INLINE void
                    310: PPCI2CInterface::setData(UInt8 newByte)
                    311: {
                    312:     *data = newByte;
                    313:     eieio();
                    314: }
                    315: 
                    316: INLINE UInt8
                    317: PPCI2CInterface::getData()
                    318: {
                    319:     return (*data);
                    320: }
                    321: 
                    322: // --------------------------------------------------------------------------
                    323: // Method: setAddressAndDirection
                    324: //
                    325: // Purpose:
                    326: //        sets the control register with the correct address and data direction.
                    327: INLINE bool
                    328: PPCI2CInterface::setAddressAndDirection()
                    329: {
                    330:     // sets the address register:
                    331:     if (isReading) {
                    332:         setAddressRegister(currentAddress, kReadADDR);        
                    333:     }
                    334:     else {
                    335:         setAddressRegister(currentAddress, kWriteADDR);       
                    336:     }
                    337: 
                    338:     // sets the subAddress:
                    339:     setSubAddress(currentSubaddress);
                    340: 
                    341:     currentState = ki2cStateWaitingForIADDR;
                    342:     setControl((I2CControl)(getControl() | kXAddrCNTRL));
                    343: 
                    344: #ifdef DEBUGMODE
                    345:     IOLog("PPCI2CInterface::setAddressAndDirection()\n");
                    346: #endif // DEBUGMODE
                    347: 
                    348:     return(true);
                    349: }
                    350: 
                    351: // --------------------------------------------------------------------------
                    352: // Method: i2cStandardSubModeInterrupts
                    353: //
                    354: // Purpose:
                    355: //        handles the interrupts and the state machine for the Standard + SubAddress mode:
                    356: bool
                    357: PPCI2CInterface::i2cStandardSubModeInterrupts(UInt8 interruptStatus)
                    358: {
                    359:     bool success = true;
                    360: 
                    361:     switch (currentState) {
                    362:         case ki2cStateWaitingForIADDR:
                    363: #ifdef DEBUGMODE            
                    364:             IOLog("ki2cStateWaitingForIADDR: ");
                    365: #endif // DEBUGMODE            
                    366: 
                    367:             // verify that correct interrupt bit set
                    368:             if ((interruptStatus & kIAddrISR) == 0) {
                    369: #ifdef DEBUGMODE            
                    370:                 IOLog("PPCI2CInterface::i2cStandardSubModeInterrupts (ki2cStateWaitingForIADDR): bad state ");
                    371: #endif
                    372:                 success = false;
                    373:             }
                    374: 
                    375:             if (success) {
                    376:                 if (getStatus() & kLastAakSTATUS) {
                    377:                         if (isReading) {
                    378:                             // if multiple bytes are to be read, set AAK bit
                    379:                             if (nBytes > 1)
                    380:                                 setControl((I2CControl)(getControl() | kAakCNTRL));
                    381:                         }
                    382:                         else {
                    383:                             // write operation
                    384:                             setData(*dataBuffer++);
                    385:                             nBytes--;
                    386:                         }
                    387: 
                    388:                         currentState = ki2cStateWaitingForIDATA;
                    389:                     }
                    390:                     else {
                    391:                         // no slave responded, so wait for STOP (control bit does not need to be set,
                    392:                         // since NAAK sets the control bit automatically)
                    393: #ifdef DEBUGMODE            
                    394:                         IOLog("...no slave...");
                    395: #endif
                    396:                         currentState = ki2cStateWaitingForISTOP;
                    397:                         success = false;
                    398:                     }
                    399:                 }
                    400:                 else {
                    401:                     // bad state, so abort command
                    402:                     abortTransfer();
                    403:                 }
                    404: 
                    405:                 // clear IADDR bit and go
                    406:                 setInterruptStatus(kIAddrISR);
                    407:             break;
                    408: 
                    409:         case ki2cStateWaitingForIDATA:
                    410: #ifdef DEBUGMODE            
                    411:             IOLog("ki2cStateWaitingForIDATA: ");
                    412: #endif
                    413:             // verify that correct interrupt bit set
                    414:             if ((interruptStatus & kIDataISR) == 0) {
                    415: #ifdef DEBUGMODE            
                    416:                 IOLog("PPCI2CInterface::i2cStandardSubModeInterrupts (ki2cStateWaitingForIDATA): bad state ");
                    417: #endif
                    418:                 success = false;
                    419:             }
                    420: 
                    421:                 if (success) {
                    422:                     if (isReading) {
                    423:                         *dataBuffer++ = getData();
                    424:                         nBytes--;
                    425: 
                    426:                         if (nBytes == 0)                       // read operation completed
                    427:                             currentState = ki2cStateWaitingForISTOP;
                    428:                         else                                   // if next byte is last byte, clear AAK bit, and state remains unchanged
                    429:                             setControl(kClrCNTRL);
                    430:                     }
                    431:                     else {
                    432:                         // write operation
                    433:                         if (getStatus() & kLastAakSTATUS) {
                    434:                             if (nBytes == 0) {
                    435:                                 // write operation completed
                    436:                                 currentState = ki2cStateWaitingForISTOP;
                    437:                                 setControl((I2CControl)(getControl() | kStopCNTRL));
                    438:                             }
                    439:                             else {
                    440:                                 // send an other byte
                    441:                                 setData(*dataBuffer++);
                    442:                                 nBytes--;
                    443:                             }
                    444:                         }
                    445:                        else {
                    446:                            // no slave responded, so wait for STOP (control bit does not need to be set,
                    447:                            // since NAAK sets the control bit automatically)
                    448: #ifdef DEBUGMODE            
                    449:                            IOLog("...no slave...");
                    450: #endif
                    451:                            currentState = ki2cStateWaitingForISTOP;
                    452:                            success = false;
                    453:                         }
                    454:                     }
                    455:                 }
                    456:                 else {
                    457:                     // bad state, so abort command
                    458:                     abortTransfer();
                    459:                 }
                    460: 
                    461:                 // clear IDATA bit and go
                    462:                 setInterruptStatus(kIDataISR);
                    463:             break;
                    464: 
                    465:         case ki2cStateWaitingForISTOP:
                    466: #ifdef DEBUGMODE
                    467:             IOLog("ki2cStateWaitingForISTOP: ");
                    468: #endif
                    469:             // verify that correct interrupt bit set
                    470:             if ((interruptStatus & kIStopISR) == 0) {
                    471: #ifdef DEBUGMODE
                    472:                 IOLog("PPCI2CInterface::i2cStandardSubModeInterrupts (ki2cStateWaitingForISTOP): bad state ");
                    473: #endif
                    474:                 success = false;
                    475:             }
                    476: 
                    477:             currentState = ki2cStateIdle;
                    478:             setInterruptStatus(kIStopISR);
                    479:            break;
                    480: 
                    481:         case ki2cStateWaitingForISTART:
                    482: #ifdef DEBUGMODE
                    483:             IOLog("ki2cStateWaitingForISTART: is not supposed to happen in this state machine ");
                    484: #endif
                    485:             break;
                    486: 
                    487:         case ki2cStateIdle:
                    488: #ifdef DEBUGMODE
                    489:             IOLog("ki2cStateIdle: ");
                    490: #endif
                    491:             break;
                    492: 
                    493:         default:
                    494:              break;
                    495:     }
                    496: #ifdef DEBUGMODE
                    497:     IOLog("\n");
                    498: #endif
                    499: 
                    500:     // tell the system that this interrupt has been serviced
                    501:     return success;
                    502: }
                    503: 
                    504: // --------------------------------------------------------------------------
                    505: // Method: abortTransfer
                    506: //
                    507: // Purpose:
                    508: //        ends the data transfer.
                    509: INLINE bool
                    510: PPCI2CInterface::abortTransfer()
                    511: {
                    512:     currentState = ki2cStateWaitingForISTOP;
                    513:     setControl((I2CControl)(getControl() | kStopCNTRL));
                    514:     return false;
                    515: }
                    516: 
                    517: // --------------------------------------------------------------------------
                    518: // Method: waitForCompletion
                    519: //
                    520: // Purpose:
                    521: //        waits until the last command was executed correctly and when it
                    522: //        happens it calls the interrupt handler. This is useful for when
                    523: //        we use this object without an interrupt handler.
                    524: bool
                    525: PPCI2CInterface::waitForCompletion()
                    526: {
                    527:     UInt16 loop = 50 + nBytes * 10;
                    528:     UInt8 intStat = getInterruptStatus();
                    529:     
                    530:     // First call to the interrupt handler in case the last command
                    531:     // is already completed
                    532:     
                    533:     //IOLog("1] Interrupt Status = 0x%02x\n", intStat);
                    534:     if (intStat & kISRMask)
                    535:         handleI2CInterrupt();
                    536: 
                    537:     // makes 10 loops for each expected interrupt with 1 millisecond delay for each loop:
                    538:     while((loop--) && (currentState != ki2cStateIdle)) {
                    539:         IOSleep(1);
                    540: 
                    541:         // If an interrupt occured handle it:
                    542:         intStat = getInterruptStatus();
                    543:         
                    544:         //IOLog("%d] Interrupt Status = 0x%02x\n", intStat);
                    545:         if (intStat & kISRMask)
                    546:             handleI2CInterrupt();
                    547:     }
                    548: 
                    549:     if (currentState != ki2cStateIdle) {
                    550: #ifdef DEBUGMODE
                    551:         IOLog("PPCI2CInterface::waitForCompletion error loop is incomplete\n");
                    552: #endif
                    553:         return false;
                    554:     }
                    555:     else {
                    556: #ifdef DEBUGMODE
                    557:         IOLog("PPCI2CInterface::waitForCompletion loop is complete\n");
                    558: #endif
                    559:         return true;        
                    560:     }
                    561: }
                    562: 
                    563: // Public Methods:
                    564: // ===============
                    565: 
                    566: // Initialize the address of the registers and the registers themselfs:
                    567: bool
                    568: PPCI2CInterface::initI2CBus(UInt8 *baseAddress, UInt8 steps)
                    569: {
                    570:     pollingMode = true;
                    571:     currentState = ki2cStateIdle;
                    572:     SetI2CBase(baseAddress, steps);
                    573: 
                    574:     return true;
                    575: }
                    576: 
                    577: // The default behavior of this class is to work in "polling mode"
                    578: // where the interrupt handler is called by a polling routine.
                    579: // However it is always possible to attahc the interrupt handler
                    580: // to an hardware interrupt and handle the transfer in the proper
                    581: // way. (the polling mode was created for the sole pourpose to
                    582: // debug the state machine).
                    583: void
                    584: PPCI2CInterface::setPollingMode(bool mode)
                    585: {
                    586:     pollingMode = mode; 
                    587: }
                    588: 
                    589: // These are to setup the mode for the I2C bus:
                    590: void
                    591: PPCI2CInterface::setDumbMode()
                    592: {
                    593:     setMode(kDumbMode);
                    594: }
                    595: 
                    596: void
                    597: PPCI2CInterface::setStandardMode()
                    598: {
                    599:     setMode(kStandardMode);
                    600: }
                    601: 
                    602: void
                    603: PPCI2CInterface::setStandardSubMode()
                    604: {
                    605:     setMode(kStandardSubMode);
                    606: }
                    607: 
                    608: void
                    609: PPCI2CInterface::setCombinedMode()
                    610: {
                    611:     setMode(kCombinedMode);
                    612: }
                    613: 
                    614: // These instead set the speed:
                    615: bool
                    616: PPCI2CInterface::setKhzSpeed(UInt speed)
                    617: {
                    618:     switch (speed)
                    619:     {
                    620:         case 100:
                    621:             setSpeed(k100KhzMode);
                    622:             break;
                    623: 
                    624:         case 50:
                    625:             setSpeed(k50KhzMode);
                    626:             break;
                    627: 
                    628:         case 25:
                    629:             setSpeed(k25KhzMode);
                    630:             break;
                    631: 
                    632:         default:
                    633: #ifdef DEBUGMODE
                    634:             IOLog("PPCI2CInterface::setKhzSpeed Can not set bus speed %d is not allowed\n", speed);
                    635: #endif
                    636:             return false;
                    637:             break;
                    638:     }
                    639: 
                    640:     return true;
                    641: }
                    642: 
                    643: // Test to read the values set by the funtions above:
                    644: bool
                    645: PPCI2CInterface::isInDumbMode()
                    646: {
                    647:     return (getMode() == kDumbMode);
                    648: }
                    649: 
                    650: bool
                    651: PPCI2CInterface::isInStandardMode()
                    652: {
                    653:     return (getMode() == kStandardMode);
                    654: }
                    655: 
                    656: bool
                    657: PPCI2CInterface::isInStandardSubMode()
                    658: {
                    659:     return (getMode() == kStandardSubMode);
                    660: }
                    661: 
                    662: bool
                    663: PPCI2CInterface::isInCombinedMode()
                    664: {
                    665:     return (getMode() == kCombinedMode);
                    666: }
                    667: 
                    668: // These instead returns the speed:
                    669: UInt
                    670: PPCI2CInterface::getKhzSpeed()
                    671: {
                    672:     switch((int)getSpeed())
                    673:     {
                    674:         case k100KhzMode:
                    675:             return (100);
                    676:             break;
                    677: 
                    678:         case k50KhzMode:
                    679:             return (50);
                    680:             break;
                    681: 
                    682:         case k25KhzMode:
                    683:             return (25);
                    684:             break;
                    685:     }
                    686: 
                    687:     // Returns 0 since the speed was not set to a real value
                    688:     return (0);
                    689: }
                    690: 
                    691: // Starts the use of the interface:
                    692: bool
                    693: PPCI2CInterface::openI2CBus(UInt8 port)
                    694: {
                    695:     portSelect = port;
                    696: 
                    697:     // Enable all the interrupts:
                    698:     setInterruptEnable((I2CInterruptEnable)(kEDataIER | kEAddrIER | kEStopIER | kEStartIER));
                    699: 
                    700:     return true;
                    701: }
                    702: 
                    703: // Writes a block of data at a given address:
                    704: bool
                    705: PPCI2CInterface::writeI2CBus(UInt8 address, UInt8 subAddress, UInt8 *newData, UInt16 len)
                    706: {
                    707:     bool success = true;
                    708: 
                    709:     // waits for the completion of the previous command
                    710:     waitForCompletion();
                    711: 
                    712:     // pointer to the data to be transfered
                    713:     dataBuffer = newData;
                    714: 
                    715:     // and the number of bytes still to transfer
                    716:     nBytes = len;
                    717: 
                    718:     // the current transfer address:
                    719:     currentAddress = address;
                    720: 
                    721:     // the current transfer subAddress:
                    722:     currentSubaddress = subAddress;
                    723: 
                    724:     // the data direction:
                    725:     isReading = false;
                    726: 
                    727:     if ((success = setAddressAndDirection()) == true ) {
                    728:         if (pollingMode)
                    729:             success = waitForCompletion();
                    730:     }
                    731: 
                    732:     return success;
                    733: }
                    734: 
                    735: // Reads a block of data at a given address:
                    736: bool
                    737: PPCI2CInterface::readI2CBus(UInt8 address, UInt8 subAddress, UInt8 *newData, UInt16 len)
                    738: {
                    739:     bool success = false;
                    740: 
                    741:     // waits for the completion of the previous command
                    742:     waitForCompletion();
                    743: 
                    744:     // pointer to the data to be received
                    745:     dataBuffer = data;
                    746: 
                    747:     // and the number of bytes still to receive
                    748:     nBytes = len;
                    749: 
                    750:     // the current transfer address:
                    751:     currentAddress = address;
                    752: 
                    753:     // the current transfer subAddress:
                    754:     currentSubaddress = subAddress;
                    755: 
                    756:     // the data direction:
                    757:     isReading = true;
                    758: 
                    759:     if ((success = setAddressAndDirection()) == true ) {
                    760:         if (pollingMode)
                    761:             success = waitForCompletion();
                    762:     }
                    763:  
                    764:     return success;
                    765: }
                    766: 
                    767: // End using the interface:
                    768: bool
                    769: PPCI2CInterface::closei2CBus()
                    770: {
                    771:     // For now empty, we may add here some deinitialization parameters.
                    772:     return true;
                    773: }
                    774: 
                    775: // The interrupt handler:
                    776: // dispatches to the correct interrupt handler according to the current mode set:
                    777: bool
                    778: PPCI2CInterface::handleI2CInterrupt()
                    779: {
                    780:     switch(lastMode)
                    781:     {
                    782:         case kDumbMode:
                    783: #ifdef DEBUGMODE
                    784:             IOLog("PPCI2CInterface::i2cStandardSubModeInterrupts kDumbMode is an unsupported mode (for now)\n");
                    785: #endif
                    786:             break;
                    787: 
                    788:         case kStandardMode:
                    789: #ifdef DEBUGMODE
                    790:             IOLog("PPCI2CInterface::i2cStandardSubModeInterrupts kStandardMode is an unsupported mode (for now)\n");
                    791: #endif
                    792:             break;
                    793: 
                    794:         case kStandardSubMode:
                    795:             return (i2cStandardSubModeInterrupts(getInterruptStatus()));
                    796:             break;
                    797: 
                    798:         case kCombinedMode:
                    799: #ifdef DEBUGMODE
                    800:             IOLog("PPCI2CInterface::i2cStandardSubModeInterrupts kCombinedMode is an unsupported mode (for now)\n");
                    801: #endif
                    802:             break;
                    803:     }
                    804: 
                    805:     // By default we fail ...
                    806:     return false;
                    807: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.